type DebounceCallback = (...args: any[]) => void;

export function debounce(
  callback: DebounceCallback,
  duration: number,
): () => void {
  let timer: NodeJS.Timeout | null = null;
  return function () {
    if (timer) {
      clearTimeout(timer);
    }
    const args: IArguments = arguments;
    timer = setTimeout(function () {
      callback(...args);
    }, duration);
  };
}

function throttle(callback, duration, immediate) {
  if (immediate === undefined) {
    immediate = true;
  }
  if (immediate) {
    let time = null;
    return function () {
      const args = arguments;
      if (!time || Date.now() - time > duration) {
        callback(...args);
        time = Date.now();
      }
    };
  } else {
    let timer = null;
    return function () {
      if (timer) {
        return;
      }
      const args = arguments;
      timer = setTimeout(function () {
        callback(...args);
        timer = null;
      }, duration);
    };
  }
}
